package com.design.reactor.stretchIO._4_masterSlaveReactorMultiThread.handler;

import com.design.reactor.stretchIO._4_masterSlaveReactorMultiThread.state.HandlerState;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//Handler線程
public class DataHandler implements Handler {

    private final SelectionKey sk;
    private final SocketChannel sc;
    private static final ThreadPoolExecutor pool =
            new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); // 線程池

    HandlerState state; // 以狀態模式實現Handler

    public DataHandler(SelectionKey sk, SocketChannel sc) {
        this.sk = sk;
        this.sc = sc;
//        state = new ReadState(); // 初始狀態設定為READING
//        pool.setMaximumPoolSize(32); // 設置線程池最大線程數
    }

    @Override
    public void processes() {
        try {
            SocketAddress remoteAddress = sc.getRemoteAddress();
            SocketAddress localAddress = sc.getLocalAddress();
            // non-blocking下不可用Readers，因為Readers不支援non-blocking
            byte[] arr = new byte[1024];
            ByteBuffer buf = ByteBuffer.wrap(arr);
            int numBytes = sc.read(buf);
            if (numBytes == -1) {
                System.out.println("[Warning!] A client has been closed.");
                closeChannel();
                return;
            }
            String str = new String(arr); // 將讀取到的byte內容轉為字符串型態
            if (!str.isEmpty()) {
                System.out.println("接收自远程地址 " + remoteAddress + "的消息内容是：" + str);
                buf.clear();
                buf.put(("发送消息 从 " + localAddress + " 到 " + remoteAddress).getBytes());
                buf.flip();
                sc.write(buf);
                sk.interestOps(SelectionKey.OP_READ); // 通過key改變通道註冊的事件
                sk.selector().wakeup(); // 使一個阻塞住的selector操作立即返回
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
//    @Override
//    public void run() {
//        try {
//            state.handle(this, sk, sc, pool);
//        } catch (IOException e) {
//            System.out.println("[Warning!] A client has been closed.");
//            closeChannel();
//        }
//    }

    public void closeChannel() {
        try {
            sk.cancel();
            sc.close();
        } catch (IOException e1) {
            e1.getLocalizedMessage();
        }
    }

    public void setState(HandlerState state) {
        this.state = state;
    }


}
